//
//  MonthSelectorView.swift
//  YOKO
//
//  Created by Zhou Xugang on 1/20/16.
//  Copyright © 2016 15Tec. All rights reserved.
//

import UIKit

protocol MonthSelectorViewDelegate: class {
    func monthSelectorViewDidSelected(month month: Int, year: Int)
}

class MonthView: UIView {
    
    var monthButtons = [UIButton]()
    
    //这里记录下已经被记录的UIButton，来快速的更新UIView
    private var __preSelectedMonthButton: UIButton?
    private var __preCurrentMonthButton: UIButton?
    
    required init?(coder aDecoder: NSCoder)
    {
        fatalError("Cannot init from coder")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.backgroundColor = YOKOColor.monthSelectorViewBackgroundColor
        //创建按钮
        for i in 1...12 {
            let newButton = UIButton(type: .System)
            newButton.setTitle("\(i)", forState: .Normal)
            newButton.tag = i
            newButton.setTitleColor(YOKOColor.monthSelectorButtonNormalForegroundColor, forState: .Normal)
            newButton.titleLabel?.font = UIFont.systemFontOfSize(20.0)
            newButton.frame = CGRectMake(0.0, 0.0, 30.0, 30.0)
            newButton.layer.cornerRadius = 15
            
            self.addSubview(newButton)
            monthButtons.append(newButton)
            
            newButton.snp_makeConstraints {
                make in
                make.size.equalTo(CGSizeMake(30.0, 30.0))
                if i <= 6 {
                    make.top.equalTo(self)
                    make.centerX.equalTo(self).multipliedBy(2.0 * CGFloat(i) / 7.0)
                }
                else {
                    make.bottom.equalTo(self).offset(-19)
                    make.centerX.equalTo(self).multipliedBy(2.0 * CGFloat(i - 6) / 7.0)
                }
            }
        }
    }
    
    convenience init() {
        self.init(frame: CGRectZero)
    }
    
    func updateUI(nowPresentedYear presentedYear: Int, currentYear: Int, currentMonth: Int, selectedYear: Int?, selectedMonth: Int?) {
        if let __preSelectedMonthButton = self.__preSelectedMonthButton {
            __setNormalButton(__preSelectedMonthButton)
            self.__preSelectedMonthButton = nil
        }
        if let __preCurrentMonthButton = self.__preCurrentMonthButton {
            __setNormalButton(__preCurrentMonthButton)
            self.__preCurrentMonthButton = nil
        }
        
        //设置selected button
        if selectedYear != nil && selectedMonth != nil && presentedYear == selectedYear && !(selectedYear == currentYear && selectedMonth == currentMonth) {
            __preSelectedMonthButton = monthButtons[selectedMonth! - 1]
            __setSelectedButton(__preSelectedMonthButton!)
        }
        
        if presentedYear == currentYear {
            __preCurrentMonthButton = monthButtons[currentMonth - 1]
            __setCurrentButton(__preCurrentMonthButton!)
        }
    }
    
    private func __setNormalButton(button: UIButton) {
        button.backgroundColor = UIColor.clearColor()
        button.setTitleColor(YOKOColor.monthSelectorButtonNormalForegroundColor, forState: .Normal)
    }
    
    private func __setSelectedButton(button: UIButton) {
        button.backgroundColor = UIColor.clearColor()
        //button.setTitleColor(YOKOColor.monthSelectorButtonHighlightedForegroundColor, forState: .Normal)
        button.backgroundColor = YOKOColor.monthSelectorButtonHighlightedForegroundColor
    }
    
    private func __setCurrentButton(button: UIButton) {
//        button.backgroundColor = YOKOColor.monthSelectorButtonHighlightedBackgroundColor
//        button.setTitleColor(YOKOColor.monthSelectorButtonNormalForegroundColor, forState: .Normal)
        //目前当前选择的月份和普通的按钮一样
        __setNormalButton(button)
    }
}

class MonthSelectorView: UIView, UIScrollViewDelegate
{
    private var __hasLayoutSubviews: Bool = false
    
    private var __selectedYear: Int?
    private var __selectedMonth: Int?
    private var __currentYear: Int = 2016
    private var __currentMonth: Int = 5
    
    private var __presentYear: Int = 2016 //当前中间的scrollView所展示的日期
    
    @IBOutlet weak var yearLabel: UILabel!
    @IBOutlet weak var nextButton: UIButton!
    @IBOutlet weak var lastButton: UIButton!
    @IBOutlet weak var monthScrollView: UIScrollView!
    var monthButtons: [UIButton]? //按照月份排好序的列表
    var monthViews = [MonthView]()
    
    //代理
    weak var delegate: MonthSelectorViewDelegate?
    
    //MARK: - 属性接口
    var selectedYear: Int? {
        get {
            return __selectedYear
        }
    }
    
    var selectedMonth: Int? {
        get {
            return __selectedMonth
        }
    }
    
    var currentYear: Int {
        get { return __currentYear }
        set {
            __currentYear = min(max(newValue, NSDate.MinDate.year), NSDate.MaxDate.year)
            __updateUI()
        }
    }
    
    var currentMonth: Int {
        get { return __currentMonth }
        set {
            __currentMonth = min(max(newValue, 1), 12)
            __updateMonthUI()
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        __configureUI()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        for _ in 0..<3 {
            let monthView = MonthView()
            monthViews.append(monthView)
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        for _ in 0..<3 {
            let monthView = MonthView()
            monthViews.append(monthView)
        }
        
        //添加阴影
        self.layer.shadowRadius = 4.0
        self.layer.shadowColor = UIColor.blackColor().CGColor
        self.layer.shadowOffset = CGSizeMake(0.0, 2.0)
        self.layer.shadowOpacity = 0.5
    }
    
    //MARK: - MARK UI层更新
    private func __configureUI() {
        if __hasLayoutSubviews == true { return }
        __hasLayoutSubviews = true
        
        //当前展示时间
        __presentYear = 2016
        
        //添加scrollView的内容
        let pageWidth = monthScrollView.frame.width
        let pageHeight = monthScrollView.frame.height
        monthScrollView.contentSize = CGSizeMake(pageWidth * 3, pageHeight)
        monthScrollView.setContentOffset(CGPointMake(pageWidth, 0.0), animated: false)
        monthScrollView.delegate = self
        
        let preMonthView = monthViews[0];
        preMonthView.frame = CGRectMake(0.0, 0.0, pageWidth, pageHeight);
        preMonthView.setNeedsLayout()
        let nowMonthView = monthViews[1];
        nowMonthView.frame = CGRectMake(pageWidth, 0.0, pageWidth, pageHeight)
        nowMonthView.setNeedsLayout()
        let nextMonthView = monthViews[2];
        nextMonthView.frame = CGRectMake(pageWidth * 2, 0.0, pageWidth, pageHeight)
        nextMonthView.setNeedsLayout()
        
        monthViews = [preMonthView, nowMonthView, nextMonthView]
        for monthButton in nowMonthView.monthButtons {
            monthButton.addTarget(self, action: #selector(MonthSelectorView.monthButtonHandler(_:)), forControlEvents: .TouchUpInside)
        }
        
        monthScrollView.addSubview(preMonthView)
        monthScrollView.addSubview(nowMonthView)
        monthScrollView.addSubview(nextMonthView)
        
        
        //将选择年份的button加入
        nextButton.tag = 1
        lastButton.tag = -1
        nextButton.addTarget(self, action: #selector(MonthSelectorView.yearButtonHandler(_:)), forControlEvents: .TouchUpInside)
        lastButton.addTarget(self, action: #selector(MonthSelectorView.yearButtonHandler(_:)), forControlEvents: .TouchUpInside)
        
        //第一次更新UI
        __updateUI()
    }
    
    private func __updateYearUI() {
        yearLabel.text = "\(__presentYear)"
    }
    
    private func __updateMonthUI() {
        monthViews[0].updateUI(nowPresentedYear: __presentYear - 1, currentYear: __currentYear, currentMonth: __currentMonth, selectedYear: __selectedYear, selectedMonth: __selectedMonth)
        monthViews[1].updateUI(nowPresentedYear: __presentYear, currentYear: __currentYear, currentMonth: __currentMonth, selectedYear: __selectedYear, selectedMonth: __selectedMonth)
        monthViews[2].updateUI(nowPresentedYear: __presentYear + 1, currentYear: __currentYear, currentMonth: __currentMonth, selectedYear: __selectedYear, selectedMonth: __selectedMonth)
    }
    
    private func __updateMonthUIForYear(monthView: MonthView, presentedYear: Int) {
        //根据当前的年份回绘制UI
        let monthButtons = monthView.monthButtons
        
        for monthButton in monthButtons {
            monthButton.backgroundColor = UIColor.clearColor()
            monthButton.setTitleColor(YOKOColor.monthSelectorButtonNormalForegroundColor, forState: .Normal)
        }
        
        if __selectedYear != nil && __selectedMonth != nil && !(__selectedYear == __currentYear && __selectedMonth == __currentMonth) && __selectedYear! == presentedYear {
            //如果当前两个值都存在并且不被当前的年月覆盖的话
            let buttonToPaint = monthButtons[__selectedMonth! - 1]
            buttonToPaint.backgroundColor = UIColor.clearColor()
            buttonToPaint.setTitleColor(YOKOColor.monthSelectorButtonHighlightedForegroundColor, forState: .Normal)
        }
        
        if presentedYear == currentYear {
            //如果当前选择的月份等于当前的月份
            let buttonToPaint = monthButtons[currentMonth - 1]
            buttonToPaint.backgroundColor = YOKOColor.monthSelectorButtonHighlightedBackgroundColor
            buttonToPaint.setTitleColor(YOKOColor.monthSelectorButtonNormalForegroundColor, forState: .Normal)
        }
    }
    
    private func __updateUI() {
        __updateYearUI()
        __updateMonthUI()
    }
    
    //MARK: - Handler
    
    func monthButtonHandler(sender: UIButton) {
        __selectedYear = __presentYear
        __selectedMonth = sender.tag
        __updateMonthUI()
        __callDelegate()
    }
    
    func yearButtonHandler(sender: UIButton) {
        
        if (sender.tag == 1 && __presentYear == NSDate.MaxDate.year) || (sender.tag == -1 && __presentYear == NSDate.MinDate.year) {
            //如果已经到达了最小的年份或者最大的年份，那么就没有任何效果
            return
        }
        
        let newContentOffset: CGFloat = sender.tag == 1 ? monthScrollView.frame.width * 2 : 0.0
        UIView.animateWithDuration(0.5, animations:
            {
                () -> Void in
                self.monthScrollView.setContentOffset(CGPointMake(newContentOffset, 0.0), animated: false)
            }) { (complete) in
                self.__presentYear += sender.tag
                self.__updateUI()
                self.monthScrollView.setContentOffset(CGPointMake(self.monthScrollView.frame.width, 0.0), animated: false)
        }
    }
    
    //MARK: - 外部的delegate
    private func __callDelegate() {
        if __selectedYear != nil && __selectedMonth != nil {
            delegate?.monthSelectorViewDidSelected(month: __selectedMonth!, year: __selectedYear!)
        }
    }
    
    //MARK: - ScrollView Delegate
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        //判断一下当前终止的位置
        
        var yearOffset = 0
        if scrollView.contentOffset.x == 0.0 {
            yearOffset = -1
        }
        else if scrollView.contentOffset.x == scrollView.frame.width * 2 {
            yearOffset = 1
        }
        
        if yearOffset == 0 {
            //用户没有滑动或者用户滑动了但是还在原来的页面
            //在最大年份和最小年份可能出现碰撞，因此要在这里重新设置setContentOffset
            
            if (monthScrollView.contentOffset.x != monthScrollView.frame.width) {
                monthScrollView.setContentOffset(CGPointMake(monthScrollView.frame.width, 0.0), animated: true)
            }
            
            return
        }
        
        //否则更新UI
        print("\(monthScrollView.frame.width)")
        __presentYear += yearOffset
        __updateUI()
        monthScrollView.setContentOffset(CGPointMake(monthScrollView.frame.width, 0.0), animated: false)
    }
    
    func scrollViewDidScroll(scrollView: UIScrollView) {
        if (__presentYear == NSDate.MinDate.year && monthScrollView.contentOffset.x < monthScrollView.frame.width) || (__presentYear == NSDate.MaxDate.year && monthScrollView.contentOffset.x > monthScrollView.frame.width) {
            //如果说当前的月份已经达到了最小月份或者最大月份就不能让再移动了
            monthScrollView.contentOffset.x = monthScrollView.frame.width
        }
    }
}
